﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Emit;
using System.Text;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;


namespace lxwmvccore
{
    public class lxwHandleFactory : PageHandlerFactory, IReadOnlySessionState
    {
        private bool flag = true;

        public override IHttpHandler GetHandler(HttpContext context, string requestType, string virtualPath, string path)
        {
            string[] urlSegments = context.Request.Url.Segments; //获取URL片段
            int urlLen = urlSegments.Length;  //获取URL的片段长度
            if (urlLen <= 1) //当前请求为根目录页面,则不进行处理
                flag = false;
            else  //当前请求不是根目录页面,进行处理
                flag = true;

            if (flag)
            {
                string conceratePath = ((char)RewriteSettings.splitter.slash).ToString();
                string slashChar = ((char)RewriteSettings.splitter.slash).ToString(); // /斜线
                string equalChar = ((char)RewriteSettings.splitter.equal).ToString(); // =等号
                string andChar = ((char)RewriteSettings.splitter.and).ToString(); // &符号
                string extension = ((char)RewriteSettings.splitter.dot).ToString().Combine(RewriteSettings.fileExtension.aspx.ToString());  // .aspx后缀

                string concerateParams = string.Empty;
                for (int i = 0; i < urlLen; i++)
                {
                    string curSegment = urlSegments[i];

                    if (curSegment.LastIndexOf(slashChar) >= 0)  //如果检测片段中带有左斜线
                        curSegment = curSegment.Substring(0, curSegment.Length - 1); //将斜线去掉

                    if (!string.IsNullOrEmpty(curSegment))
                    {
                        if (curSegment.Contains(equalChar)) //如果带有等号,则表明应该进行 ***.aspx?id=1 类似的拼接
                        {
                            if (i == urlLen - 1)
                                concerateParams = concerateParams.Combine(curSegment);
                            else
                                concerateParams = concerateParams.Combine(curSegment.Combine(andChar));
                        }
                        else if (!curSegment.EndsWith(extension)) //如果不是以.aspx结尾的
                            conceratePath = conceratePath.Combine(curSegment.Combine(extension));
                        else
                            conceratePath = conceratePath.Combine(curSegment);
                    }
                }

                string newPath = context.Server.MapPath(conceratePath); //得到物理目录

                context.RewritePath(conceratePath, string.Empty, concerateParams); //重写路径,并传入parameters

                try
                {
                    //web.config 中的 <compilation><buildProviders> 节注册一个
                    //IHttpHandler iHandler = PageParser.GetCompiledPageInstance(conceratePath, newPath, context);  //重写handler对象
                    IHttpHandler iHandler = new lxwHandler();
                    return iHandler; 
                }
                catch (Exception ex)
                {
                    throw new Exception(ex.Message);
                }
            }
            else
            {
                return base.GetHandler(context, requestType, virtualPath, path);
            }
        }
    }


    /// <summary>
    /// 拦截请求并处理
    /// </summary>
    public class lxwHandler : IHttpHandler, IRequiresSessionState
    {
        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/plain";
            context.Response.Write("Hello World");
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }

    public class RewriteSettings
    {
        public enum splitter
        {
            slash = '/',
            and = '&',
            equal = '=',
            dot = '.',
            none
        }

        public enum fileExtension
        {
            aspx,
            asp,
            html,
            jsp,
            htm,
            none
        }
    }

    public static class StringExtension
    {
        public static string Combine(this string strOriginal, string strAppend)
        {
            return strOriginal + strAppend;
        }
    }
}